﻿using Consul;
using ELF.Core;
using Microsoft.Extensions.Options;

namespace ELF;

public class ConsulHostedService : IHostedService
{
    private readonly IConsulClient _consulClient;
    private readonly ILogger<ConsulHostedService> _logger;
    private string? _registrationId;
    private readonly ConsulOptions _options;

    public ConsulHostedService(
        IConsulClient consulClient,
        IOptions<ConsulOptions> options,
        ILogger<ConsulHostedService> logger)
    {
        _consulClient = consulClient;
        _options = options.Value;
        _logger = logger;
    }

    public async Task StartAsync(CancellationToken cancellationToken)
    {
        var serviceId = $"{_options.ServiceName}-{Guid.NewGuid()}";
        Uri uri;
        //调试模式
#if DEBUG
        var serviceUri = new Uri(_options.ServiceAddress);
        var environmentUri = new Uri(Environment.GetEnvironmentVariable("ASPNETCORE_URLS") ?? "http://localhost:8080");
        uri = new Uri($"{serviceUri.Scheme}://{serviceUri.Host}:{environmentUri.Port}");
#else
        uri = new Uri(_options.ServiceAddress);
#endif
        //if (Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") == "Development")
        //{
        //    var serviceUri = new Uri(_options.ServiceAddress);
        //    var environmentUri = new Uri(Environment.GetEnvironmentVariable("ASPNETCORE_URLS") ?? "http://localhost:8080");
        //    uri = new Uri($"{serviceUri.Scheme}://{serviceUri.Host}:{environmentUri.Port}");
        //}
        //else
        //{
        //    uri = new Uri(_options.ServiceAddress);
        //}
        var registration = new AgentServiceRegistration
        {
            ID = serviceId,
            Name = _options.ServiceName,
            Address = uri.Host,
            Port = uri.Port,
            Tags = [],
            Check = new AgentServiceCheck
            {
                HTTP = $"{uri.Scheme}://{uri.Host}:{uri.Port}{_options.HealthCheckEndpoint}",
                Interval = TimeSpan.FromSeconds(10),
                Timeout = TimeSpan.FromSeconds(5),
                DeregisterCriticalServiceAfter = TimeSpan.FromMinutes(1)
            }
        };
        await _consulClient.Agent.ServiceRegister(registration, cancellationToken);
    }

    public async Task StopAsync(CancellationToken cancellationToken)
    {
        if (!string.IsNullOrEmpty(_registrationId))
        {
            await _consulClient.Agent.ServiceDeregister(_registrationId, cancellationToken);
        }
    }
}